<template>
  <div class="o-input-text">
    <Input
      :placeholder="renderOpts.props.placeholder"
      v-model="value"
      @on-change="onChange"
      @on-blur="onBlur"
      @on-focus="onFocus"
      @on-enter="onEnter"
      @mouseleave="onMouseleave"
      @mouseenter="onMouseenter"
      :disabled="renderOpts.props.disabled"
      :class="'align-' + align"
      ref="input"
    />
  </div>
</template>
<script lang="ts">
import { T_srv, Tsrv, vue } from '@/services';
import { Input } from 'view-design';

@T_srv.comp
export default class oInput extends vue {
  // modify by wiz
  public G_compName: string = 'oInput';

  /**
   * props
   */
  @T_srv.prop() renderOpts: any;

  @T_srv.prop() params: any;

  private value = null;

  private startValue = null;

  private align = 'left';

  /**
   * data
   */
  @T_srv.watch('params')
  onParamsChange(val) {
    this.initProps();
    this.setValue();
  }

  created() {}

  mounted() {
    this.initProps();
    this.setValue();
    this.addCustomEvents();
  }

  private initProps() {
    if (this.params.property) {
      const items = this.params.$form.items;
      const find = Tsrv.utils.find(
        items,
        el => el.field === this.params.property
      );
      if (find) {
        this.align = find.align || 'left';
      }
    } else {
      this.align = this.params.column.align || 'left';
    }
  }

  public focus() {
    (this.$refs.input as Input).focus();
    ((this.$refs.input as Input).$el as HTMLInputElement).click();
  }

  public resetValue() {
    this.setValue(null);
    this.setTableValue(null);
  }

  setValue(val: null | string | undefined = undefined) {
    if (this.params.property) {
      this.value =
        val !== undefined ? val : this.params.data[this.params.property];
    } else if (this.params.column) {
      this.value =
        val !== undefined ? val : this.params.row[this.params.column.property];
    }
  }

  setTableValue(val: string | null) {
    if (this.params.property) {
      this.params.data[this.params.property] = val === '' ? null : val;
    } else {
      this.params.row[this.params.column.property] = val === '' ? null : val;
    }
  }

  onFocus() {
    this.startValue = this.getValue();
    this.emitEvent('focus');
  }

  onBlur() {
    this.emitEvent('blur');
    const value = this.getValue();
    value !== this.startValue && this.emitEvent('dochange');
  }

  onChange(e) {
    const val = e.target.value;
    val === '' ? this.setTableValue(null) : this.setTableValue(val);
    this.emitEvent('dochange');
  }

  onEnter(e) {
    this.emitEvent('enter');
  }

  onMouseleave(e) {
    this.emitEvent('mouseleave');
  }

  onMouseenter(e) {
    this.emitEvent('mouseenter');
  }

  getValue() {
    return this.params.property
      ? this.params.data[this.params.property]
      : this.params.row[this.params.column.property];
  }

  emitEvent(event: string) {
    const ev = this.renderOpts.events;
    // const params = Tsrv.utils.clone(this.params, true);
    // params.from = 'inputtext';
    const params = Tsrv.utils.cloneNoMatchVue(this.params, true);
    params['from'] = 'inputtext';
    for (const action in ev) {
      if (ev[action] && action === `on-${event}`) {
        // ev[action](params);
        ev[action](params, event);
      }
    }
  }

  beforeDestroy() {
    this.destroyCustomEvents();
  }

  /**
   * @description: 给input元素添加自定义事件
   *  原有事件：blur,change,enter
   *  添加事件：mouseenter,mouseleave
   * @return {*}
   * @author: swc
   * @Date: 2024-01-11 13:16:42
   * @LastEditors: swc
   * @LastEditTime: Do not edit
   */
  private addCustomEvents() {
    ((this.$refs.input as Input).$el as HTMLInputElement).addEventListener(
      'mouseenter',
      this.onMouseenter
    );
    ((this.$refs.input as Input).$el as HTMLInputElement).addEventListener(
      'mouseleave',
      this.onMouseleave
    );
  }

  private destroyCustomEvents() {
    ((this.$refs.input as Input).$el as HTMLInputElement).removeEventListener(
      'mouseenter',
      this.onMouseenter
    );
    ((this.$refs.input as Input).$el as HTMLInputElement).removeEventListener(
      'mouseleave',
      this.onMouseleave
    );
  }
}
</script>
